package com.du.linandroid.util;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.util.Log;

import junit.framework.Assert;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by Administrator on 2018/1/19.
 */

public class WXUtil {

        /** max decode picture size */
        private static final int MAX_DECODE_PICTURE_SIZE = 1920 * 1440;
        /** log tag */
        private static final String TAG = "SDK_Sample.Util";

        /**
         * 微信分享图片，缩略图要求32K以内，NOTE: The file size should be within 32KB；
         * 经测试，等于32K也不可以分享
         * @param image
         * @param needRecycle
         * @return
         */
        public static byte[] compressImage2ByteArray(Bitmap image, boolean needRecycle) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
            int quality = 100;

            while (baos.toByteArray().length / 1024 >= 32) {  // 循环判断如果压缩后图片是否大于32kb,大于继续压缩
                if (quality <= 0) {
                    return baos.toByteArray();
                }
                baos.reset();// 重置baos即清空baos
                // Some formats, like PNG which is lossless, will ignore the quality setting
                image.compress(CompressFormat.JPEG, quality, baos);
                quality -= 10;// 每次都减少10
            }
            if (needRecycle) {
                image.recycle();
            }
            return baos.toByteArray();
        }

        public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            bmp.compress(CompressFormat.PNG, 100, output);
            if (needRecycle) {
                bmp.recycle();
            }

            byte[] result = output.toByteArray();
            try {
                output.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            return result;
        }

        public static byte[] getHtmlByteArray(final String url) {
            URL htmlUrl = null;
            InputStream inStream = null;
            try {
                htmlUrl = new URL(url);
                URLConnection connection = htmlUrl.openConnection();
                HttpURLConnection httpConnection = (HttpURLConnection) connection;
                int responseCode = httpConnection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    inStream = httpConnection.getInputStream();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            byte[] data = inputStreamToByte(inStream);

            return data;
        }

        public static byte[] inputStreamToByte(InputStream is) {
            try {
                ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
                int ch;
                while ((ch = is.read()) != -1) {
                    bytestream.write(ch);
                }
                byte imgdata[] = bytestream.toByteArray();
                bytestream.close();
                return imgdata;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        public static byte[] readFromFile(String fileName, int offset, int len) {
            if (fileName == null) {
                return null;
            }

            File file = new File(fileName);
            if (!file.exists()) {
                Log.i(TAG, "readFromFile: file not found");
                return null;
            }

            if (len == -1) {
                len = (int) file.length();
            }

            Log.d(TAG, "readFromFile : offset = " + offset + " len = " + len
                    + " offset + len = " + (offset + len));

            if (offset < 0) {
                Log.e(TAG, "readFromFile invalid offset:" + offset);
                return null;
            }
            if (len <= 0) {
                Log.e(TAG, "readFromFile invalid len:" + len);
                return null;
            }
            if (offset + len > (int) file.length()) {
                Log.e(TAG, "readFromFile invalid file len:" + file.length());
                return null;
            }

            byte[] b = null;
            try {
                RandomAccessFile in = new RandomAccessFile(fileName, "r");
                b = new byte[len]; // 创建合适文件大小的数组
                in.seek(offset);
                in.readFully(b);
                in.close();

            } catch (Exception e) {
                Log.e(TAG, "readFromFile : errMsg = " + e.getMessage());
                e.printStackTrace();
            }
            return b;
        }

        public static Bitmap extractThumbNail(final String path, final int height, final int width, final boolean crop) {
            Assert.assertTrue(path != null && !path.equals("") && height > 0 && width > 0);

            BitmapFactory.Options options = new BitmapFactory.Options();

            try {
                options.inJustDecodeBounds = true;
                Bitmap tmp = BitmapFactory.decodeFile(path, options);
                if (tmp != null) {
                    tmp.recycle();
                    tmp = null;
                }

                Log.d(TAG, "extractThumbNail: round=" + width + "x" + height + ", crop=" + crop);
                final double beY = options.outHeight * 1.0 / height;
                final double beX = options.outWidth * 1.0 / width;
                Log.d(TAG, "extractThumbNail: extract beX = " + beX + ", beY = " + beY);
                options.inSampleSize = (int) (crop ? (beY > beX ? beX : beY) : (beY < beX ? beX : beY));
                if (options.inSampleSize <= 1) {
                    options.inSampleSize = 1;
                }

                // NOTE: out of memory error
                while (options.outHeight * options.outWidth / options.inSampleSize > MAX_DECODE_PICTURE_SIZE) {
                    options.inSampleSize++;
                }

                int newHeight = height;
                int newWidth = width;
                if (crop) {
                    if (beY > beX) {
                        newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
                    } else {
                        newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
                    }
                } else {
                    if (beY < beX) {
                        newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
                    } else {
                        newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
                    }
                }

                options.inJustDecodeBounds = false;

                Log.i(TAG, "bitmap required size=" + newWidth + "x" + newHeight + ", orig=" + options.outWidth + "x" + options.outHeight + ", sample=" + options.inSampleSize);
                Bitmap bm = BitmapFactory.decodeFile(path, options);
                if (bm == null) {
                    Log.e(TAG, "bitmap decode failed");
                    return null;
                }

                Log.i(TAG, "bitmap decoded size=" + bm.getWidth() + "x" + bm.getHeight());
                final Bitmap scale = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true);
                if (scale != null) {
                    bm.recycle();
                    bm = scale;
                }

                if (crop) {
                    final Bitmap cropped = Bitmap.createBitmap(bm, (bm.getWidth() - width) >> 1, (bm.getHeight() - height) >> 1, width, height);
                    if (cropped == null) {
                        return bm;
                    }

                    bm.recycle();
                    bm = cropped;
                    Log.i(TAG, "bitmap croped size=" + bm.getWidth() + "x" + bm.getHeight());
                }
                return bm;

            } catch (final OutOfMemoryError e) {
                Log.e(TAG, "decode bitmap failed: " + e.getMessage());
                options = null;
            }

            return null;
        }
}
